/*
 * Copyright (c) 2022 Kirky
 * Licensed under the Open Software Licence, Version 3.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/osl-3.0.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bei.lingluan.generalDialog;


import com.bei.lingluan.ResourceTable;
import com.bei.lingluan.utils.ResourceHelper;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.service.WindowManager;
import ohos.app.Context;
import ohos.media.image.PixelMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author Kirky
 * @version 1.0
 * @description General Dialog Helper
 * @date 2021/12/10
 */
public class GeneralDialogHelper {
    private static final int MAX_BUTTON_NUMBER = 3;
    private static final int DIALOG_WIDTH_VP = 328;

    private final String[] mButtonTexts = new String[MAX_BUTTON_NUMBER];
    private final int[] mButtonTypes = new int[MAX_BUTTON_NUMBER];
    private final ClickedListener[] mButtonListeners = new ClickedListener[MAX_BUTTON_NUMBER];
    private final List<String> mClickableContextTexts = new ArrayList<>();
    private final List<ClickedListener> mClickableContextListeners = new ArrayList<>();
    private float dim = -1f;
    private int alignment = LayoutAlignment.BOTTOM;
    private boolean mOutsideTouchClosable = false;
    private String mTitle;

    private String mContent;

    private PixelMap image;

    private int mIconId;

    private Component mCustomComponent;

    private int mButtonNum = 0;

    private int clickableContentNum = 0;

    private CommonDialog mCommonDialog;

    public void show() {
        if (mCommonDialog != null) {
            mCommonDialog.show();
            if (dim >= 0) {
                changeDialogDim(mCommonDialog, dim);
            }
        }
    }

    public void remove() {
        if (mCommonDialog != null) {
            mCommonDialog.destroy();
        }
    }

    private void changeDialogDim(CommonDialog dialog, float dim) {
        Optional<WindowManager.LayoutConfig> configOpt = dialog.getWindow().getLayoutConfig();
        configOpt.ifPresent(config -> {
            config.dim = dim;
            dialog.getWindow().setLayoutConfig(config);
        });
    }

    public interface ClickedListener {
        /**
         * Normal click time
         *
         * @param dialog
         */
        void normalListener(GeneralDialogHelper dialog);
    }

    public static class Builder {
        private final GeneralDialogHelper mGeneralDialog;

        private final Context mContext;

        /**
         * initialization
         */
        public Builder(Context context) {
            mContext = context;
            mGeneralDialog = new GeneralDialogHelper();
        }

//        Set area

        /**
         * Set pop-up direction
         */
        public Builder setAlignment(int alignment) {
            mGeneralDialog.alignment = alignment;
            return this;
        }

        /**
         * Set window brightness
         */
        public Builder setDim(float dim) {
            if (dim > 1) {
                mGeneralDialog.dim = 1;
            } else if (dim < 0) {
                mGeneralDialog.dim = 0;
            } else {
                mGeneralDialog.dim = dim;
            }
            return this;
        }

        /**
         * Sets whether windows can be closed outside the window
         */
        public Builder setOutsideTouchClosable(boolean closable) {
            mGeneralDialog.mOutsideTouchClosable = closable;
            return this;
        }

//        Content area

        /**
         * Set title
         */
        public Builder setTitle(String title) {
            mGeneralDialog.mTitle = title;
            return this;
        }

        /**
         * Set content
         */
        public Builder setContent(String content) {
            mGeneralDialog.mContent = content;
            return this;
        }

        /**
         * Set icon
         * (Icon of content area)
         */
        public Builder setIcon(int id) {
            mGeneralDialog.mIconId = id;
            return this;
        }

        /**
         * Set presentation image
         * 250vp*250vp
         */
        public Builder setImage(PixelMap image) {
            mGeneralDialog.image = image;
            return this;
        }

        /**
         * Add bottom button
         */
        public Builder addButton(String text, int type, ClickedListener listener) {
            if (mGeneralDialog.mButtonNum >= MAX_BUTTON_NUMBER) {
                return this;
            }
            mGeneralDialog.mButtonTexts[mGeneralDialog.mButtonNum] = text;
            mGeneralDialog.mButtonTypes[mGeneralDialog.mButtonNum] = type;
            mGeneralDialog.mButtonListeners[mGeneralDialog.mButtonNum] = listener;
            mGeneralDialog.mButtonNum++;
            return this;
        }

        /**
         * Add clickable content in the content area
         */
        public Builder addClickableContent(String text, ClickedListener listener) {
            mGeneralDialog.mClickableContextTexts.add(text);
            mGeneralDialog.mClickableContextListeners.add(listener);
            mGeneralDialog.clickableContentNum++;
            return this;
        }

        /**
         * Add custom component
         */
        public Builder addCustomComponent(Component component) {
            mGeneralDialog.mCustomComponent = component;
            return this;
        }

        /**
         * Create dialog
         */
        public GeneralDialogHelper create() {
            CommonDialog sDialog = new CommonDialog(mContext);
            sDialog.setSize(AttrHelper.fp2px(DIALOG_WIDTH_VP, mContext), ComponentContainer.LayoutConfig.MATCH_CONTENT);
            sDialog.setAlignment(mGeneralDialog.alignment);
            sDialog.setOffset(0, (int) ResourceHelper.getFloat(mContext, ResourceTable.Float_spacing_huge, 0));
            sDialog.setTransparent(true);
            sDialog.setContentCustomComponent(initDialog());
            sDialog.setAutoClosable(mGeneralDialog.mOutsideTouchClosable);
            mGeneralDialog.mCommonDialog = sDialog;
            System.out.println("----->create!!!!");
            return mGeneralDialog;
        }

        private Component initDialog() {
            Component dialogLayout = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_layout_general_dialog, null, false);
            dialogLayout.setBackground(new ShapeElement() {{
                setRgbColor(RgbColor.fromArgbInt(ResourceHelper.getColorInt(mContext, ResourceTable.Color_bg_dialog_light, 0xffffff)));
                setCornerRadius(ResourceHelper.getFloat(mContext, ResourceTable.Float_dialog_corner_radius, 0));
            }});

            Text textTitle = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_title);
            if (mGeneralDialog.mTitle != null) {
                textTitle.setText(mGeneralDialog.mTitle);
                textTitle.setVisibility(Component.VISIBLE);
            }
            Component bottomLayoutMain = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_bottom_layout);
            if (mGeneralDialog.mCustomComponent != null) {
                DependentLayout contentLayout = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_content_layout);
                contentLayout.addComponent(mGeneralDialog.mCustomComponent);
            } else if (mGeneralDialog.image != null) {
                Image image = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_image);
                image.setPixelMap(mGeneralDialog.image);
                image.setVisibility(Component.VISIBLE);
            } else if (mGeneralDialog.mIconId != 0) {
                Image imageIcon = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_icon);
                imageIcon.setPixelMap(mGeneralDialog.mIconId);
                imageIcon.setVisibility(Component.VISIBLE);
                Component titleLayout = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_title_layout);
                titleLayout.setVisibility(Component.HIDE);
            } else if (mGeneralDialog.clickableContentNum > 0) {
                initClickableContent(dialogLayout);
            } else if (mGeneralDialog.mContent != null) {
                Text textContentMain = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_content_main);
                textContentMain.setText(mGeneralDialog.mContent);
                textContentMain.setVisibility(Component.VISIBLE);
                bottomLayoutMain.setVisibility(Component.VISIBLE);
            }
            initButton(dialogLayout, bottomLayoutMain);
            return dialogLayout;
        }

        /**
         * Initialize clickable text area
         *
         * @param dialogLayout
         */
        private void initClickableContent(Component dialogLayout) {
            DirectionalLayout clickableContentLayout = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_clickable_content_layout);
            for (int i = 0; i < mGeneralDialog.clickableContentNum; i++) {
                if (i == 0) {
                    clickableContentLayout.setVisibility(Component.VISIBLE);
                }
                Text text = new Text(mContext);
                clickableContentLayout.addComponent(text);
                DirectionalLayout.LayoutConfig config = new DirectionalLayout.LayoutConfig();
                config.height = DirectionalLayout.LayoutConfig.MATCH_CONTENT;
                config.width = DirectionalLayout.LayoutConfig.MATCH_CONTENT;
                config.weight = 1;
                text.setLayoutConfig(config);
                text.setText(mGeneralDialog.mClickableContextTexts.get(i));
                int currentIndex = i;
                text.setClickedListener(component -> mGeneralDialog.mClickableContextListeners.get(currentIndex).normalListener(mGeneralDialog));
                text.setFont(Font.DEFAULT_BOLD);
                text.setTextColor(ResourceHelper.getColor(mContext, ResourceTable.Color_global_text_emphasized, Color.BLUE.getValue()));
                text.setTextSize((int) ResourceHelper.getFloat(mContext, ResourceTable.Float_text_size_content, 0));
                text.setMultipleLine(false);
                text.setScrollable(true);
            }
        }

        /**
         * Initialize bottom button
         *
         * @param dialogLayout
         * @param bottomLayoutMain
         */
        private void initButton(Component dialogLayout, Component bottomLayoutMain) {
            DirectionalLayout operationLayout = dialogLayout.findComponentById(ResourceTable.Id_generalDialog_operation_layout);
            float totalWeight = 1.25f;
            for (int i = 0; i < mGeneralDialog.mButtonNum; i++) {
                if (i == 0) {
                    operationLayout.setVisibility(Component.VISIBLE);
                    bottomLayoutMain.setVisibility(Component.VISIBLE);
                }
                Button button = new Button(mContext);
                operationLayout.addComponent(button);
                DirectionalLayout.LayoutConfig config = new DirectionalLayout.LayoutConfig();
                config.height = (int) ResourceHelper.getFloat(mContext, ResourceTable.Float_button_height, 0);
                config.width = DirectionalLayout.LayoutConfig.MATCH_PARENT;
                config.weight = 1;
                int spacingHorizontal = (int) ResourceHelper.getFloat(mContext, ResourceTable.Float_spacing_mini, 0);
                config.setMargins(spacingHorizontal, 0, spacingHorizontal, 0);
                button.setLayoutConfig(config);
                if (i != 0) {
                    totalWeight = i + 1.0f;
                }
                button.setBackground(new GeneralButtonElement(mContext, mGeneralDialog.mButtonTypes[i]));
                if (mGeneralDialog.mButtonTypes[i] == GeneralButtonElement.TYPE_NORMAL) {
                    button.setTextColor(new Color(ResourceHelper.getColorInt(mContext, ResourceTable.Color_text_color_light, 0xFFFFFF)));
                } else {
                    button.setTextColor(new Color(ResourceHelper.getColorInt(mContext, ResourceTable.Color_color_normal, 0xFFFFFF)));
                }
                button.setText(mGeneralDialog.mButtonTexts[i]);
                int currentIndex = i;

                button.setClickedListener(component -> mGeneralDialog.mButtonListeners[currentIndex].normalListener(mGeneralDialog));

                button.setFont(Font.DEFAULT_BOLD);
                button.setTextSize((int) ResourceHelper.getFloat(mContext, ResourceTable.Float_button_size, 0));
                button.setMultipleLine(false);
                button.setTruncationMode(Text.TruncationMode.ELLIPSIS_AT_END);
                button.setPaddingLeft(spacingHorizontal);
                button.setPaddingRight(spacingHorizontal);
            }
            operationLayout.setTotalWeight(totalWeight);
        }
    }
}